package org.example.test915.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.example.common.bean.CommonPage;
import org.example.common.constant.WsConstant;
import org.example.common.powerjob.PowerJobDelayTaskUtil;
import org.example.test915.entity.bo.PageUserInfoParam;
import org.example.test915.entity.bo.UserInfoParam;
import org.example.test915.entity.convert.UserInfoConvert;
import org.example.test915.entity.po.UserInfoPO;
import org.example.test915.entity.vo.UserInfoVO;
import org.example.test915.mpservice.UserInfoMpService;
import org.example.test915.service.UserInfoService;
import org.example.testWebsocket.entity.WsMsg;
import org.example.testWebsocket.service.WebSocketService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

@Slf4j
@Service
public class UserInfoServiceImpl implements UserInfoService {
    @Resource
    private UserInfoMpService userInfoMpService;
    @Resource
    private UserInfoConvert userInfoConvert;
    @Resource
    private PowerJobDelayTaskUtil powerJobDelayTaskUtil;

    @Resource
    private WebSocketService webSocketService;

    @Resource(name = "taskExecutor")
    private Executor executor;

    // 从配置文件注入 jobId
    @Value("${powerjob.worker.my-core-service}")
    private Long jobId;

    @Override
    public void saveOrUpdate(UserInfoParam param) {
        UserInfoPO po = new UserInfoPO();
        po.setUsername(param.getUsername());
        po.setAnalysis(param.getAnalysis());
        //单个保存
        userInfoMpService.save(po);
        userInfoMpService.saveOrUpdate(po);
        //批量保存: 一个保存失败则全部失败
        List<UserInfoPO> list = new ArrayList<>();
        userInfoMpService.saveBatch(list);
        userInfoMpService.saveOrUpdateBatch(list);
        // 修改
        userInfoMpService.update(new LambdaUpdateWrapper<UserInfoPO>()
                .eq(UserInfoPO::getUsername, "username")
                .eq(UserInfoPO::getId, "id")
                .set(UserInfoPO::getAnalysis, "analyyyyyy")
        );
        //po一定包含id，否则不报错也不起作用
        userInfoMpService.updateById(po);
        // 异步线程池
        // 这里通过@Resource注解来注入名为taskExecutor的bean,所以通过@Bean注解来找taskExecutor即可
        executor.execute(() -> addResult(param));
        // 若想获取返回值那么需要completeFuture

    }

    private void addResult(UserInfoParam param) {

    }

    private List<String> addReturnResult(UserInfoParam param) {
        return null;

    }

    @Override
    public void delete(Long id) {
        userInfoMpService.removeById(id);
    }

    @Override
    public UserInfoVO queryById(Long id) {
        UserInfoPO po = userInfoMpService.getById(id);
        return userInfoConvert.po2Vo(po);
    }


    @Override
    public CommonPage<UserInfoVO> page(PageUserInfoParam param) {
        // 分页查询时创建并立即触发延时任务
        try {
            // 延迟10秒后执行任务（用于测试，实际使用可以改为分钟或小时）
            Long delayMillTime = 1000L; // 10秒 = 10 * 1000毫秒


            String username  = param.getUsername()==null? "a": param.getUsername();
            // 准备任务参数
            Map<String, Object> taskParams = new java.util.HashMap<>();
            taskParams.put("username", username);
            taskParams.put("startTime", "b");
            taskParams.put("endTime", "c");
            taskParams.put("operation", "export_user_info"); // 任务类型

            // 创建并立即触发延时任务（任务会在10秒后执行）
            // 注意：这个方法会立即触发，PowerJob Server 会等待指定时间后才执行
            Long instanceId = powerJobDelayTaskUtil.createDelayTask(jobId, delayMillTime, taskParams);
            log.info("创建并触发延时任务成功, jobId: {}, instanceId: {}, 将在{}秒后执行", jobId, instanceId, delayMillTime / 1000);

            // instanceId 的作用：
            // 1. 用于追踪这个任务实例的执行状态和日志
            // 2. 可以通过 powerJobDelayTaskUtil.stopInstance(instanceId) 取消任务
            // 3. 可以存储到数据库，关联到业务数据，便于后续查询
            // 4. 用于查看任务执行历史

            // 如果需要取消任务，可以这样调用：
            // powerJobDelayTaskUtil.stopInstance(instanceId);
        } catch (Exception e) {
            log.error("创建延时任务失败", e);
            // 延时任务创建失败不影响查询业务，只记录日志
        }

        Integer pageNum = param.getPageNum() == null ? 1 : param.getPageNum();
        Integer pageSize = param.getPageSize() == null ? 10 : param.getPageSize();
        Page<UserInfoPO> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<UserInfoPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(param.getUsername()), UserInfoPO::getUsername, param.getUsername())
                .le(ObjectUtil.isNotEmpty(param.getStartTime()), UserInfoPO::getCreateTime, param.getStartTime())
                .ge(ObjectUtil.isNotEmpty(param.getEndTime()), UserInfoPO::getCreateTime, param.getEndTime())
                .orderByDesc(UserInfoPO::getUpdateTime);
        Page<UserInfoPO> pagePo = userInfoMpService.page(page, queryWrapper);
        Page<UserInfoVO> pageVo = userInfoConvert.po2voPage(pagePo);
        // 查询完成后发送wsSocket消息 ： 先发送到redis频道--》转发websocket消息
        WsMsg ws= new WsMsg();
        ws.setDestination(String.format(WsConstant.USERS,"abc"));
        ws.setMessageContent("here is my word");
        webSocketService.sendMsg(ws);
        return CommonPage.restPage(pageVo.getRecords(), page.getTotal(), pageNum, pageSize);
    }
}
